#include "esp_err.h"
#include "esp_log.h"
#include "esp_check.h"
#include "driver/i2c.h"
#include "driver/gpio.h"
#include "driver/spi_master.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
#include "esp_lvgl_port.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_lcd_gc9a01.h"
#include "lv_demos.h"
#include "esp_lcd_touch_cst816s.h"

static const char *TAG = "example";

// The pixel number in horizontal and vertical
#define EXAMPLE_LCD_H_RES (240)
#define EXAMPLE_LCD_V_RES (240)

#define EXAMPLE_LCD_PIXEL_CLK_HZ (20 * 1000 * 1000)
#define EXAMPLE_LCD_CMD_BITS (8)
#define EXAMPLE_LCD_PARAM_BITS (8)
#define EXAMPLE_LCD_COLOR_SPACE (ESP_LCD_COLOR_SPACE_BGR)  // 恢复BGR颜色空间
#define EXAMPLE_LCD_BITS_PER_PIXEL (16)
#define EXAMPLE_LCD_DRAW_BUFF_DOUBLE (1)
#define EXAMPLE_LCD_DRAW_BUFF_HEIGHT (50)
#define EXAMPLE_LCD_BL_ON_LEVEL (1)
#define EXAMPLE_LCD_DRAW_BUFF_SIZE (EXAMPLE_LCD_H_RES * 50)
#define EXAMPLE_LCD_DRAW_BUFF_ALLOC_PSRAM (0)
#define EXAMPLE_LCD_DRAW_BUFF_ALLOC_SPIRAM (0)

// Intel 8080 并口接口引脚定义
#define EXAMPLE_LCD_GPIO_CS (GPIO_NUM_1)
#define EXAMPLE_LCD_GPIO_DC (GPIO_NUM_2)
#define EXAMPLE_LCD_GPIO_WR (GPIO_NUM_8)  // 硬件控制写使能
#define EXAMPLE_LCD_GPIO_RD (GPIO_NUM_NC)  // 硬件控制读使能
#define EXAMPLE_LCD_GPIO_RST (GPIO_NUM_7) // 复位引脚，如需要可设置具体GPIO
#define EXAMPLE_LCD_GPIO_DB0 (GPIO_NUM_9)
#define EXAMPLE_LCD_GPIO_DB1 (GPIO_NUM_3)
#define EXAMPLE_LCD_GPIO_DB2 (GPIO_NUM_10)
#define EXAMPLE_LCD_GPIO_DB3 (GPIO_NUM_4)
#define EXAMPLE_LCD_GPIO_DB4 (GPIO_NUM_12)
#define EXAMPLE_LCD_GPIO_DB5 (GPIO_NUM_5)
#define EXAMPLE_LCD_GPIO_DB6 (GPIO_NUM_11)
#define EXAMPLE_LCD_GPIO_DB7 (GPIO_NUM_6)
#define EXAMPLE_LCD_GPIO_BL (GPIO_NUM_13)

// 触摸屏引脚定义
#define EXAMPLE_LCD_TOUCH_I2C_NUM (I2C_NUM_0)
#define EXAMPLE_LCD_TOUCH_I2C_CLK_SPEED_HZ (400000)
#define EXAMPLE_LCD_TOUCH_I2C_SCL (GPIO_NUM_17)
#define EXAMPLE_LCD_TOUCH_I2C_SDA (GPIO_NUM_16)
#define EXAMPLE_LCD_TOUCH_INT (GPIO_NUM_15)
#define EXAMPLE_LCD_TOUCH_RST (GPIO_NUM_NC)  // 未连接复位引脚

// MOTOR控制引脚定义
#define EXAMPLE_MOTOR_GPIO (GPIO_NUM_21)

/* LCD IO and panel */
static esp_lcd_panel_io_handle_t lcd_io = NULL;
static esp_lcd_panel_handle_t lcd_panel = NULL;

/* LVGL display and touch */
static lv_display_t *lvgl_disp = NULL;
static lv_indev_t *lvgl_touch_indev = NULL;

static esp_lcd_touch_handle_t tp = NULL;
static esp_lcd_panel_io_handle_t touch_io_handle = NULL;

// MOTOR控制状态
static volatile bool motor_active = false;

// MOTOR控制函数
static void motor_control(bool enable)
{
    motor_active = enable;
    gpio_set_level(EXAMPLE_MOTOR_GPIO, enable ? 1 : 0);
    ESP_LOGI(TAG, "MOTOR %s", enable ? "启动" : "停止");
}

// 添加清理函数
static void app_lcd_cleanup(void)
{
    if (lcd_panel)
    {
        esp_lcd_panel_del(lcd_panel);
        lcd_panel = NULL;
    }
    if (lcd_io)
    {
        esp_lcd_panel_io_del(lcd_io);
        lcd_io = NULL;
    }
}

static void app_touch_cleanup(void)
{
    if (tp)
    {
        esp_lcd_touch_del(tp);
        tp = NULL;
    }
    if (touch_io_handle)
    {
        esp_lcd_panel_io_del(touch_io_handle);
        touch_io_handle = NULL;
    }
}

static void app_motor_cleanup(void)
{
    motor_control(false);  // 确保MOTOR停止
    gpio_reset_pin(EXAMPLE_MOTOR_GPIO);
}

static void app_lvgl_cleanup(void)
{
    if (lvgl_disp)
    {
        lvgl_port_remove_disp(lvgl_disp);
        lvgl_disp = NULL;
    }
    lvgl_port_deinit();
}

static esp_err_t app_lcd_init(void)
{
    esp_err_t ret = ESP_OK;

    /* LCD backlight */
    gpio_config_t bk_gpio_config = {
        .mode = GPIO_MODE_OUTPUT,
        .pin_bit_mask = 1ULL << EXAMPLE_LCD_GPIO_BL};
    ESP_GOTO_ON_ERROR(gpio_config(&bk_gpio_config), err, TAG, "GPIO config failed");

    /* LCD initialization */
    ESP_LOGD(TAG, "Initialize Intel 8080 bus");
    
    esp_lcd_i80_bus_handle_t i80_bus = NULL;
    esp_lcd_i80_bus_config_t bus_config = {
        .clk_src = LCD_CLK_SRC_DEFAULT,
        .dc_gpio_num = EXAMPLE_LCD_GPIO_DC,
        .wr_gpio_num = EXAMPLE_LCD_GPIO_WR,
        .data_gpio_nums = {
            EXAMPLE_LCD_GPIO_DB0,
            EXAMPLE_LCD_GPIO_DB1,
            EXAMPLE_LCD_GPIO_DB2,
            EXAMPLE_LCD_GPIO_DB3,
            EXAMPLE_LCD_GPIO_DB4,
            EXAMPLE_LCD_GPIO_DB5,
            EXAMPLE_LCD_GPIO_DB6,
            EXAMPLE_LCD_GPIO_DB7,
        },
        .bus_width = 8,
        .max_transfer_bytes = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_V_RES * sizeof(uint16_t),  // 增加传输缓冲区大小
        .psram_trans_align = 64,
        .sram_trans_align = 4,
    };
    ESP_GOTO_ON_ERROR(esp_lcd_new_i80_bus(&bus_config, &i80_bus), err, TAG, "I80 bus init failed");
    
    ESP_LOGD(TAG, "Install panel IO");
    esp_lcd_panel_io_i80_config_t io_config = {
        .cs_gpio_num = EXAMPLE_LCD_GPIO_CS,
        .pclk_hz = EXAMPLE_LCD_PIXEL_CLK_HZ,
        .trans_queue_depth = 20,
        .dc_levels = {
            .dc_idle_level = 0,
            .dc_cmd_level = 0,
            .dc_dummy_level = 0,
            .dc_data_level = 1,
        },
        .flags = {
            .swap_color_bytes = true,  // 在I80层交换颜色字节
        },
        .on_color_trans_done = NULL,
        .user_ctx = NULL,
        .lcd_cmd_bits = EXAMPLE_LCD_CMD_BITS,
        .lcd_param_bits = EXAMPLE_LCD_PARAM_BITS,
    };
    ESP_GOTO_ON_ERROR(esp_lcd_new_panel_io_i80(i80_bus, &io_config, &lcd_io), err, TAG, "New panel IO failed");

    ESP_LOGD(TAG, "Install LCD driver");
    const esp_lcd_panel_dev_config_t panel_config = {
        .reset_gpio_num = EXAMPLE_LCD_GPIO_RST,
        .color_space = EXAMPLE_LCD_COLOR_SPACE,
        .bits_per_pixel = EXAMPLE_LCD_BITS_PER_PIXEL,
    };
    ESP_GOTO_ON_ERROR(esp_lcd_new_panel_gc9a01(lcd_io, &panel_config, &lcd_panel), err, TAG, "New panel failed");

    esp_lcd_panel_reset(lcd_panel);
    esp_lcd_panel_init(lcd_panel);
    esp_lcd_panel_disp_on_off(lcd_panel, true);
    esp_lcd_panel_invert_color(lcd_panel, true);

    /* LCD backlight on */
    ESP_ERROR_CHECK(gpio_set_level(EXAMPLE_LCD_GPIO_BL, EXAMPLE_LCD_BL_ON_LEVEL));

    return ret;

err:
    if (ret != ESP_OK)
    {
        app_lcd_cleanup();
    }
    return ret;
}

static esp_err_t app_lvgl_init(void)
{
    /* Initialize LVGL */
    const lvgl_port_cfg_t lvgl_cfg = {
        .task_priority = 4,
        .task_stack = 8192,
        .task_affinity = 0,
        .task_max_sleep_ms = 2,
        .timer_period_ms = 1};
    ESP_RETURN_ON_ERROR(lvgl_port_init(&lvgl_cfg), TAG, "LVGL port initialization failed");

    /* Add LCD screen */
    ESP_LOGD(TAG, "Add LCD screen");
    const lvgl_port_display_cfg_t disp_cfg = {
        .io_handle = lcd_io,
        .panel_handle = lcd_panel,
        .buffer_size = EXAMPLE_LCD_H_RES * EXAMPLE_LCD_DRAW_BUFF_HEIGHT * sizeof(uint16_t),
        .double_buffer = EXAMPLE_LCD_DRAW_BUFF_DOUBLE,
        .hres = EXAMPLE_LCD_H_RES,
        .vres = EXAMPLE_LCD_V_RES,
        .monochrome = false,
        .rotation = {
            .swap_xy = false,
            .mirror_x = true,
            .mirror_y = false,
        },
        .flags = {
            .buff_dma = true,
            .buff_spiram = false,
            .swap_bytes = false,  // 改为false，不交换字节
        }};
    lvgl_disp = lvgl_port_add_disp(&disp_cfg);

    return ESP_OK;
}

static esp_err_t app_motor_init(void)
{
    ESP_LOGI(TAG, "初始化MOTOR控制GPIO%d", EXAMPLE_MOTOR_GPIO);
    
    // 重置GPIO引脚状态
    gpio_reset_pin(EXAMPLE_MOTOR_GPIO);
    
    gpio_config_t motor_gpio_config = {
        .mode = GPIO_MODE_OUTPUT,
        .pin_bit_mask = 1ULL << EXAMPLE_MOTOR_GPIO,
        .pull_up_en = GPIO_PULLUP_ENABLE,
        .pull_down_en = GPIO_PULLDOWN_DISABLE,
        .intr_type = GPIO_INTR_DISABLE,
    };
    
    ESP_RETURN_ON_ERROR(gpio_config(&motor_gpio_config), TAG, "MOTOR GPIO配置失败");
    
    // 初始状态设为低电平（MOTOR停止）
    ESP_RETURN_ON_ERROR(gpio_set_level(EXAMPLE_MOTOR_GPIO, 0), TAG, "MOTOR GPIO初始状态设置失败");
    
    motor_active = false;
    ESP_LOGI(TAG, "MOTOR控制GPIO初始化完成");
    
    return ESP_OK;
}

// 使用espressif__esp_lcd_touch_cst816s组件初始化触摸屏
static esp_err_t app_touch_init(void)
{
    ESP_LOGI(TAG, "初始化CST816S触摸屏");
    
    /* Initialize I2C */
    const i2c_config_t i2c_conf = {
        .mode = I2C_MODE_MASTER,
        .sda_io_num = EXAMPLE_LCD_TOUCH_I2C_SDA,
        .scl_io_num = EXAMPLE_LCD_TOUCH_I2C_SCL,
        .sda_pullup_en = GPIO_PULLUP_ENABLE,
        .scl_pullup_en = GPIO_PULLUP_ENABLE,
        .master.clk_speed = 100000,  // 使用100kHz时钟频率
    };
    ESP_RETURN_ON_ERROR(i2c_param_config(EXAMPLE_LCD_TOUCH_I2C_NUM, &i2c_conf), TAG, "I2C config failed");
    ESP_RETURN_ON_ERROR(i2c_driver_install(EXAMPLE_LCD_TOUCH_I2C_NUM, i2c_conf.mode, 0, 0, 0), TAG, "I2C install failed");

    /* Add I2C IO for touch */
    esp_lcd_panel_io_i2c_config_t tp_io_config = ESP_LCD_TOUCH_IO_I2C_CST816S_CONFIG();
    ESP_RETURN_ON_ERROR(esp_lcd_new_panel_io_i2c((esp_lcd_i2c_bus_handle_t)EXAMPLE_LCD_TOUCH_I2C_NUM, &tp_io_config, &touch_io_handle), TAG, "Touch panel IO init failed");

    /* Add touch screen */
    esp_lcd_touch_config_t tp_cfg = {
        .x_max = EXAMPLE_LCD_H_RES,
        .y_max = EXAMPLE_LCD_V_RES,
        .rst_gpio_num = EXAMPLE_LCD_TOUCH_RST,
        .int_gpio_num = EXAMPLE_LCD_TOUCH_INT,
        .levels = {
            .reset = 0,
            .interrupt = 0,
        },
        .flags = {
            .swap_xy = 0,
            .mirror_x = 0,
            .mirror_y = 0,
        },
    };
    ESP_RETURN_ON_ERROR(esp_lcd_touch_new_i2c_cst816s(touch_io_handle, &tp_cfg, &tp), TAG, "Touch panel init failed");
    
    ESP_LOGI(TAG, "CST816S触摸屏初始化完成");
    
    return ESP_OK;
}

// 按钮事件处理函数
static void button_event_handler(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    
    if (code == LV_EVENT_PRESSED) {
        motor_control(true);
    } else if (code == LV_EVENT_RELEASED) {
        motor_control(false);
    }
}

// 创建圆形按钮UI
static void create_circular_button_ui(void)
{
    // 创建屏幕对象
    lv_obj_t * scr = lv_scr_act();
    lv_obj_set_style_bg_color(scr, lv_color_hex(0x000000), LV_PART_MAIN);  // 黑色背景
    
    // 创建圆形按钮
    lv_obj_t * btn = lv_btn_create(scr);
    lv_obj_set_size(btn, 120, 120);  // 设置按钮大小为120x120像素
    lv_obj_center(btn);  // 居中显示
    
    // 设置按钮为圆形
    lv_obj_set_style_radius(btn, 60, LV_PART_MAIN);  // 半径为60，形成圆形
    
    // 设置按钮样式
    lv_obj_set_style_bg_color(btn, lv_color_hex(0x2196F3), LV_PART_MAIN);  // 蓝色背景
    lv_obj_set_style_bg_color(btn, lv_color_hex(0x1976D2), LV_STATE_PRESSED);  // 按下时深蓝色
    lv_obj_set_style_shadow_width(btn, 10, LV_PART_MAIN);  // 阴影效果
    lv_obj_set_style_shadow_color(btn, lv_color_hex(0x666666), LV_PART_MAIN);
    
    // 添加按钮文本
    lv_obj_t * label = lv_label_create(btn);
    lv_label_set_text(label, "MOTOR");
    lv_obj_set_style_text_color(label, lv_color_hex(0xFFFFFF), LV_PART_MAIN);  // 白色文字
    lv_obj_set_style_text_font(label, &lv_font_montserrat_18, LV_PART_MAIN);  // 18号字体
    lv_obj_center(label);
    
    // 添加事件处理函数
    lv_obj_add_event_cb(btn, button_event_handler, LV_EVENT_ALL, NULL);
    
    // 添加状态指示标签
    lv_obj_t * status_label = lv_label_create(scr);
    lv_label_set_text(status_label, "MLKJ-1.28");
    lv_obj_set_style_text_color(status_label, lv_color_hex(0xFFFFFF), LV_PART_MAIN);
    lv_obj_set_style_text_font(status_label, &lv_font_montserrat_14, LV_PART_MAIN);
    lv_obj_align(status_label, LV_ALIGN_BOTTOM_MID, 0, -20);
}

void app_main(void)
{
    esp_err_t ret;

    /* MOTOR initialization */
    ret = app_motor_init();
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "MOTOR init failed");
        return;
    }

    /* LCD HW initialization */
    ret = app_lcd_init();
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "LCD init failed");
        app_motor_cleanup();
        return;
    }

    /* Touch initialization */
    ret = app_touch_init();
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "Touch init failed");
        app_lcd_cleanup();
        app_motor_cleanup();
        return;
    }

    /* LVGL initialization */
    ret = app_lvgl_init();
    if (ret != ESP_OK)
    {
        ESP_LOGE(TAG, "LVGL init failed");
        app_touch_cleanup();
        app_lcd_cleanup();
        app_motor_cleanup();
        return;
    }

    /* Add touch input device to LVGL */
    const lvgl_port_touch_cfg_t touch_cfg = {
        .disp = lvgl_disp,
        .handle = tp,
    };
    lvgl_touch_indev = lvgl_port_add_touch(&touch_cfg);
    
    ESP_LOGI(TAG, "触摸输入设备已添加到LVGL");

    /* Show circular button UI */
    if (lvgl_port_lock(0))
    {
        create_circular_button_ui();
        lvgl_port_unlock();
    }

    ESP_LOGI(TAG, "MLKJ-1.28 系统启动完成");
    ESP_LOGI(TAG, "触摸按钮控制MOTOR震动 - GPIO%d", EXAMPLE_MOTOR_GPIO);
    
    // 主循环 - 简化为定期任务处理
    while (1) {
        vTaskDelay(pdMS_TO_TICKS(1000));  // 1秒循环间隔
    }
}